#ifndef __UTIL__FUNCTION_HPP__
#define __UTIL__FUNCTION_HPP__

#include "cache_strategy.hpp"
#include "point.hpp"

#include <string>
#include <utility>
#include <vector>

namespace util {
  /** @brief A utility class for functions.

    This class is a function object that encapsulates functions in the
    VLAB function formats (original and fver 1 1).

    This class has three possible caching strategies: none,
    pre-evaluation and lazy-evaluation.  The cache is based the cache
    implementation by Pavol Federl in the previous function
    implementation.

    This spline evalutation is based on that in Foley \& Vandamme.
  */
  class function {
  public:
    function();
    function(std::string filename, util::cache_strategy strategy = all, unsigned int samples = 1000, double error = 0.001);
    function(const function& f);

    double operator()(double x) const;

    void reread();

  private:
    void   reset_cache();
    double eval(d01 x) const;

    util::point P(double x) const;
    double      N(int k, int t, double u) const;
    double      Nk1(int k, double u) const;
    double      Nkt(int k, int t, double u) const;
    int         Uk(int j) const;

    std::string    filename;
    cache_strategy strategy;
    unsigned int   samples;
    double         error;

    std::vector<util::point> control_points;

    mutable std::vector<std::pair<bool, double> > cache;
  };
}

#endif
